﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FlickrNet;
using WeatherFrame;
using System.Threading;

namespace WeatherImageCollection
{
    class FlickrPhotoSearch
    {
        Flickr flickr;

        public FlickrPhotoSearch()
        {
            string apikey = "b99afea8628c6874313a4aaddedbd492"; // secret: 49d5faea1068ad31 
            flickr = new Flickr(apikey);
        }
        Dictionary<string, bool> doneDict = new Dictionary<string, bool>();

        public IEnumerable<Photo> Search(string searchText)
        {
            bool isWeatherFrame = searchText.Contains("weatherframe");
            // perform search
            var pso = new PhotoSearchOptions
            {
                Text = searchText,
                PerPage = 500,
                InGallery = true,// - too restrictive
                SortOrder = PhotoSearchSortOrder.InterestingnessDescending,
                //GeoContext = FlickrNet.GeoContext.Outdoors,// - unfortunately returns no pictures if uncommented
                Extras = PhotoSearchExtras.OriginalDimensions | PhotoSearchExtras.OwnerName | PhotoSearchExtras.Views
            };
            if (!isWeatherFrame)
            {
                pso.Licenses.Add(LicenseType.AttributionCC);
                pso.Licenses.Add(LicenseType.AttributionNoDerivativesCC);
                pso.Licenses.Add(LicenseType.AttributionNoncommercialCC);
                pso.Licenses.Add(LicenseType.AttributionNoncommercialNoDerivativesCC);
                pso.Licenses.Add(LicenseType.AttributionNoncommercialShareAlikeCC);
                pso.Licenses.Add(LicenseType.AttributionShareAlikeCC);
            }
            Console.WriteLine(searchText + " in galleries");
            PhotoCollection pc = flickr.PhotosSearch(pso);
            foreach (var photo in pc)
            {
                if (doneDict.ContainsKey(photo.PhotoId)) continue;
                doneDict[photo.PhotoId] = true;
                if (!IsPhotoOk(photo, false)) continue;
                yield return photo;
            }
            pso.InGallery = false;
            for (int page = 1; page < 3; page++)
            {
                Console.WriteLine(searchText + " in faves (page " + page+")");
                pso.Page = page;

                for (int tries = 0; tries < 5; tries++)
                {
                    pc = null;
                    try
                    {
                        pc = flickr.PhotosSearch(pso);
                    }
                    catch (Exception ex)
                    {
                        Thread.Sleep(1000);
                    }
                    if (pc == null)
                    {
                        Console.WriteLine("failed");
                        continue;
                    }
                    foreach (var photo in pc)
                    {
                        if (doneDict.ContainsKey(photo.PhotoId)) continue;
                        doneDict[photo.PhotoId] = true;
                        if (!isWeatherFrame && !IsPhotoOk(photo, true)) continue;
                        yield return photo;
                    }
                }
            }
        }

        double targetAspectRatio = 480.0 / 800.0;


        bool IsPhotoOk(Photo photo,bool mustHaveFaves)
        {
            if (photo.OriginalWidth == 0) return false;
            double aspectRatio = ((double)photo.OriginalHeight) / photo.OriginalWidth;
            if (Math.Abs(targetAspectRatio - aspectRatio) > 0.1) return false;
                if (mustHaveFaves)
                {
                    try
                    {
                        var favs = flickr.PhotosGetFavorites(photo.PhotoId);
                        if (favs.Count < 2) return false;
                    }
                    catch (Exception ex)
                    {
                    }

                }
                return true;
            
        }

        internal void GetPhotoInfo(ConditionImage im)
        {
            PhotoInfo info = flickr.PhotosGetInfo(im.FlickrId);
            im.SmallUri = info.SmallUrl;
            im.Credit = info.OwnerRealName;
            if (string.IsNullOrEmpty(info.OwnerRealName)) im.Credit = info.OwnerUserName;
            im.Title = info.Title;
        }
    }
}
